package com.xbongbong.paas.service.workflow.comment.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.ProcessTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.service.workflow.comment.WorkflowCommentPushMsgService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.message.constant.ApprovalPushConstant;
import com.xbongbong.pro.message.constant.ProcessPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowTaskEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskNodeEntity;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import com.xbongbong.workflow.model.WorkflowTaskNodeModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author chenpeng
 * @version 1.0
 * @date 2021-05-11 20:20
 * @description
 */
@Service
@Slf4j
public class WorkflowCommentPushMsgServiceImpl implements WorkflowCommentPushMsgService {
    
    @Resource
    private UserModel userModel;
    @Resource
    private WorkflowTaskNodeModel workflowTaskNodeModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private MessageService messageService;
    
    @Override
    public void pushComment(UserVO loginUser, Integer businessType, Long refId, String corpid, List<String> atUserIds, String content, BusinessCommentEnum businessCommentEnum, Boolean isInform) throws XbbException {
        WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(refId, corpid);
        if (workflowTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        //勾选消息通知
        //isInform不为空且值为true表示勾选了
        if (Objects.nonNull(isInform) && isInform) {
            //同时勾选了和@了创建人，只发送勾选的消息通知
            atUserIds.remove(workflowTaskEntity.getCreatorId());
            //查询任务
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(ParameterConstant.DEL, 0);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.TASK_ID, refId);
            params.put(ParameterConstant.ORDER_BY_STR, " id DESC ");
            List<WorkflowTaskNodeEntity> entities = workflowTaskNodeModel.findEntities(params);
            if (CollectionUtils.isEmpty(entities)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            //查询表单模板
            String formName;
            if (Objects.equals(workflowTaskEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(workflowTaskEntity.getFormId(), corpid);
                if (workOrderFormEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                formName = workOrderFormEntityExt.getName();
            } else {
                PaasFormEntity paasFormEntity = paasFormModel.getByKey(workflowTaskEntity.getFormId(), corpid);
                if (paasFormEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                formName = paasFormEntity.getName();
            }

            String creatorId = workflowTaskEntity.getCreatorId();
            UserEntity userEntity = userModel.getByKey(creatorId, corpid);
            if (Objects.isNull(userEntity)) {
                return;
            }
            if (!Objects.equals(creatorId, loginUser.getUserId())) {
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(workflowTaskEntity.getAppId(), workflowTaskEntity.getMenuId(), workflowTaskEntity.getFormId(), Collections.singletonList(workflowTaskEntity.getId()), workflowTaskEntity.getSaasMark(), workflowTaskEntity.getBusinessType(), refId, entities.get(0).getId(), ProcessTypeEnum.CC.getValue());
                String pushContentStr = userEntity.getName() + I18nMessageUtil.getMessage(CommonConstant.OF) + formName;
                String pushContent = String.format(I18nMessageUtil.getMessage(ApprovalPushConstant.APPROVALPUSH_COMMENT), loginUser.getName(), pushContentStr);
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(loginUser.getCorpid(), Collections.singletonList(creatorId), Collections.singletonList(refId), 0, null, I18nMessageUtil.getMessage(ApprovalPushConstant.APPROVALPUSH_COMMENT_TITLE), pushContent, null, options);
                messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_PUSH_ADD_COMMENT);
            }
        }
        //@消息通知
        pushProcessComment(loginUser, refId, atUserIds);
    }
    
    /**
     * 这个方法工作流好像用不上,走的是pushProcessComment
     * @param loginUser
     * @param refId                 业务数据id
     * @param corpid                公司id
     * @param atUserIds             @的人员
     * @param businessCommentEnum   业务类型
     * @param paasFormDataEntityExt 业务数据
     * @param content
     * @throws XbbException
     */
    @Override
    public void pushCommentAt(UserVO loginUser, Long refId, String corpid, List<String> atUserIds, BusinessCommentEnum businessCommentEnum, PaasFormDataEntityExt paasFormDataEntityExt, String content) throws XbbException {
        
        Integer businessType = businessCommentEnum.getBusinessType();
        atUserIds.remove(loginUser.getUserId());
        
        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getMenuId(), paasFormDataEntityExt.getFormId(), refId, Collections.singletonList(refId), SaasMarkEnum.SAAS.getCode(), businessType, businessType);
        
        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, atUserIds, Collections.singletonList(refId), 0, null, "", "", null, options);

        messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_COMMENT_AT);
    }
    
    @Override
    public void pushProcessComment(UserVO loginUser, Long taskId, List<String> atUserIds) throws XbbException {
        String corpid = loginUser.getCorpid();
        String userName = loginUser.getName();
        // 移除当前操作人
        atUserIds.remove(loginUser.getUserId());
    
        WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(taskId, corpid);
        if (workflowTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        
        //查询任务
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.DEL, 0);
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.TASK_ID, taskId);
        params.put(ParameterConstant.ORDER_BY_STR, " id DESC ");
        List<WorkflowTaskNodeEntity> entities = workflowTaskNodeModel.findEntities(params);
        if (CollectionUtils.isEmpty(entities)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
        }
        //转map
        Map<String, WorkflowTaskNodeEntity> nodeTaskMap = entities.stream().filter(v -> Objects.equals(v.getTaskType(), TaskTypeEnum.UNTREATED.getType())).collect(Collectors.toMap(WorkflowTaskNodeEntity::getUserId, t -> t));

        //查询表单模板
        String formName;
        if (Objects.equals(workflowTaskEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(workflowTaskEntity.getFormId(), corpid);
            if (workOrderFormEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            formName = workOrderFormEntityExt.getName();
        } else {
            PaasFormEntity paasFormEntity = paasFormModel.getByKey(workflowTaskEntity.getFormId(), corpid);
            if (paasFormEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            formName = paasFormEntity.getName();
        }
        
        UserEntity userEntity = userModel.getByKeyIngoreDel(workflowTaskEntity.getCreatorId(), corpid);
        
        //遍历要@的名单
        for (String atUserId : atUserIds) {
            //如果未处理的任务map里包含要@的对象
            if (nodeTaskMap.containsKey(atUserId)) {
                WorkflowTaskNodeEntity taskNodeEntity = nodeTaskMap.get(atUserId);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(workflowTaskEntity.getAppId(), workflowTaskEntity.getMenuId(), workflowTaskEntity.getFormId(), Collections.singletonList(workflowTaskEntity.getId()), workflowTaskEntity.getSaasMark(), workflowTaskEntity.getBusinessType(), taskId, taskNodeEntity.getId(), ProcessTypeEnum.TODO.getValue());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(loginUser.getCorpid(), Collections.singletonList(atUserId), Collections.singletonList(taskId), 0, null, I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_AT_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_AT_CONTENT), userName, userEntity.getName(), formName), null, options);
                messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_COMMENT_AT);
            } else {
                //否则就是已处理 - 变成CC
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(workflowTaskEntity.getAppId(), workflowTaskEntity.getMenuId(), workflowTaskEntity.getFormId(), Collections.singletonList(workflowTaskEntity.getId()), workflowTaskEntity.getSaasMark(), workflowTaskEntity.getBusinessType(), taskId, entities.get(0).getId(), ProcessTypeEnum.CC.getValue());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(loginUser.getCorpid(), Collections.singletonList(atUserId), Collections.singletonList(taskId), 0, null, I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_AT_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_AT_CONTENT), userName, userEntity.getName(), formName), null, options);
                messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_COMMENT_AT);
            }
        }
    }
    
    @Override
    public void pushCommentDelete(UserVO loginUser, Integer businessType, Long refId, String corpid, String content, BusinessCommentEnum businessCommentEnum) throws XbbException {
        if (Objects.isNull(businessCommentEnum)) {
            return;
        }
        WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(refId, corpid);
        if (workflowTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        //获取创建人
        String creatorId = workflowTaskEntity.getCreatorId();
        //根据公司创建人设置推送pushContent?
        List<UserEntity> userList = getUserEntities(loginUser, creatorId);
        String pushTitle = I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_TITLE);
        String pushContent = String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_DEL_CONTENT), loginUser.getName(), CollectionUtils.isEmpty(userList) ? "" : userList.get(0).getName());
        
        //不推送本人
        if (!Objects.equals(loginUser.getUserId(), creatorId)) {
            List<String> pushUserList = Collections.singletonList(creatorId);

            Map<String, Object> params = new HashMap<>();
            params.put(ParameterConstant.DEL, 0);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.TASK_ID,refId);
            params.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            List<WorkflowTaskNodeEntity> workflowTaskNodeEntities = workflowTaskNodeModel.findEntities(params);

            PushRefTypePojo.Options options = new PushRefTypePojo.Options(workflowTaskEntity.getAppId(), workflowTaskEntity.getMenuId(), workflowTaskEntity.getFormId(), Collections.singletonList(refId), workflowTaskEntity.getSaasMark(), workflowTaskEntity.getBusinessType(), refId, workflowTaskNodeEntities.get(0).getId(), ProcessTypeEnum.TODO.getValue());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(refId), 0, null, pushTitle, pushContent, null, options);
            messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_COMMENT_DEL);
        }
        
    }
    
    @Override
    public void pushCommentEdit(UserVO loginUser, Integer businessType, Long refId, String corpid, List<String> atUserIds, String content, BusinessCommentEnum businessCommentEnum) throws XbbException {
        if (Objects.isNull(businessCommentEnum)) {
            return;
        }
        WorkflowTaskEntity entity = workflowTaskModel.getByKey(refId, corpid);
        if (entity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        
        String createrId = entity.getCreatorId();
        
        List<UserEntity> userList = getUserEntities(loginUser, createrId);
        String pushTitle = I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_TITLE);
        String pushContent = String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_COMMENT_EDIT_CONTENT), loginUser.getName(), CollectionUtils.isEmpty(userList) ? "" : userList.get(0).getName());
        
        //不推送本人
        if (!Objects.equals(loginUser.getUserId(), createrId)) {
            List<String> pushUserList = Collections.singletonList(createrId);

            Map<String, Object> params = new HashMap<>();
            params.put(ParameterConstant.DEL, 0);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.TASK_ID,refId);
            params.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            List<WorkflowTaskNodeEntity> workflowTaskNodeEntities = workflowTaskNodeModel.findEntities(params);

            PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(), entity.getFormId(), Collections.singletonList(refId), entity.getSaasMark(), entity.getBusinessType(), refId, workflowTaskNodeEntities.get(0).getId(), ProcessTypeEnum.TODO.getValue());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(refId), 0, null, pushTitle, pushContent, null, options);
            messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.APPROVAL_COMMENT_EDIT);
        }
        pushProcessComment(loginUser, refId, atUserIds);
    }
    
    private List<UserEntity> getUserEntities(UserVO loginUser, String createrId) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, loginUser.getCorpid());
        param.put(ParameterConstant.DEL, 0);
        param.put(ParameterConstant.USER_ID, createrId);
        return userModel.findEntitys(param);
    }
    
}
